package com.apes.fn.scm.rebatePolicy.service;

import com.alibaba.fastjson.JSONObject;
import com.apes.fn.scm.rebatePolicy.model.*;
import com.apes.fn.scm.rebatePolicy.repository.RebateCalculationRepository;
import com.apes.fn.scm.rebatePolicy.repository.RebatePolicyExecuteRepository;
import com.apes.fn.scm.rebatePolicy.repository.RebatePolicyRepository;
import com.apes.framework.api.DomainService;

import com.apes.framework.jpa.generator.service.SequenceService;
import com.apes.framework.plugin.esb.api.SimpleRequest;
import com.apes.framework.util.DateUtil;
import com.apes.framework.util.MapUtil;
import com.apes.scm.account.account.model.Cooperation;
import com.apes.scm.account.account.repository.CooperationRepository;
import com.apes.scm.income.model.Income;
import com.apes.scm.income.model.IncomeItem;
import com.apes.scm.invoice.model.InvoiceItem;
import com.apes.scm.invoice.repository.InvoiceItemRepository;
import com.apes.scm.invoice.repository.InvoiceRepository;
import com.apes.scm.masterdata.enumeration.repository.EnumerationRepository;
import com.apes.scm.masterdata.frame.repository.DeptRepository;
import com.apes.scm.masterdata.party.model.PartyRole;
import com.apes.scm.masterdata.party.repository.PartyRoleRepository;
import com.apes.scm.masterdata.product.model.Product;
import com.apes.scm.sal.saleReturn.SaleReturn;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;


/**
 * @Author: cyy
 * @CreateTime: 2023-09-20 17:44
 * @Description: 返利政策
 * @Version: 1.0
 */
@Service("rebatePolicyService")
public class RebatePolicyService extends DomainService {
    @Autowired
    private RebatePolicyRepository rebatePolicyRepository;
    @Autowired
    private EnumerationRepository enumerationRepository;
    @Autowired
    private InvoiceItemRepository invoiceItemRepository;
    @Autowired
    private CooperationRepository cooperationRepository;
    @Autowired
    private RebatePolicyExecuteRepository rebatePolicyExecuteRepository;
    @Autowired
    private PartyRoleRepository partyRoleRepository;
    @Autowired
    private RebateCalculationRepository rebateCalculationRepository;
    @Autowired
    private DeptRepository deptRepository;
    @Autowired
    private SequenceService sequenceService;



    /**
     * 创建
     *
     * @param request
     * @return
     */
    public RebatePolicy create(SimpleRequest request) {
        RebatePolicy rebatePolicy = request.getO(RebatePolicy.class);
        rebatePolicy.setState("create");
        return rebatePolicyRepository.saveAndFlush(rebatePolicy);
    }
    /**
     * 修改
     *
     * @param request
     * @return
     */
    public RebatePolicy update(SimpleRequest request) {
        RebatePolicy rebatePolicy = request.getO(RebatePolicy.class);
        return rebatePolicyRepository.saveAndFlush(rebatePolicy);
    }

    /**
     * 审核
     *
     * @param request
     * @return
     */
    public RebatePolicy approve(SimpleRequest request) {
        RebatePolicy rebatePolicy = request.getO(RebatePolicy.class);
        rebatePolicy.setState("approve");
        rebatePolicy.setApproveUid(getPerson(request));
        rebatePolicy.setApproveDate(new Date());
        //保存执行表
        saveExecute(rebatePolicy);
        return rebatePolicyRepository.saveAndFlush(rebatePolicy);
    }

    /**
     * 终止
     *
     * @param request
     * @return
     */
    public RebatePolicy repeal(SimpleRequest request) {
        RebatePolicy rebatePolicy = request.getO(RebatePolicy.class);
        rebatePolicy.setState("repeal");
        rebatePolicy.setRepealUid(getPerson(request));
        rebatePolicy.setRepealDate(new Date());
        List<RebatePolicyExecute> rebatePolicyExecuteList = rebatePolicyExecuteRepository.findAllByRebatePolicy(rebatePolicy);
        rebatePolicyExecuteList.forEach(rebatePolicyExecute -> rebatePolicyExecuteRepository.delete(rebatePolicyExecute));
        return rebatePolicyRepository.saveAndFlush(rebatePolicy);
    }

    /**
     * 删除
     *
     * @param request
     * @return
     */
    public String delete(SimpleRequest request) {
        RebatePolicy rebatePolicy = request.getO(RebatePolicy.class);
        rebatePolicyRepository.delete(rebatePolicy);
        return "删除成功";
    }

    /**
     * 保存返利执行表
     *
     * @param rebatePolicy
     * @return
     */
    public void saveExecute(RebatePolicy rebatePolicy){
        //供应商
        rebatePolicy.getRebatePolicySupplierItems().forEach(rebatePolicySupplier -> {
            //创建返利执行表基础数据
            RebatePolicyExecute rebatePolicyExecute = createExecute(rebatePolicy);
            //返利政策明细号
            rebatePolicyExecute.setRebatePolicyItemId(rebatePolicySupplier.getId());
            //返利率/额
            rebatePolicyExecute.setRebate(rebatePolicySupplier.getRebate());
            //计算基数
            rebatePolicyExecute.setRebateBenchmark(rebatePolicySupplier.getRebateBenchmark());
            //优先级
            rebatePolicyExecute.setPriority(1);
            //返利维度
            rebatePolicyExecute.setRebateDimension(enumerationRepository.findOne("002468"));
            rebatePolicyExecuteRepository.saveAndFlush(rebatePolicyExecute);
        });
        //品类
        rebatePolicy.getRebatePolicyClassifyItems().forEach(rebatePolicyClassify -> {
            //创建返利执行表基础数据
            RebatePolicyExecute rebatePolicyExecute = createExecute(rebatePolicy);
            //返利政策明细号
            rebatePolicyExecute.setRebatePolicyItemId(rebatePolicyClassify.getId());
            //返利率/额
            rebatePolicyExecute.setRebate(rebatePolicyClassify.getRebate());
            //计算基数
            rebatePolicyExecute.setRebateBenchmark(rebatePolicyClassify.getRebateBenchmark());
            //优先级
            rebatePolicyExecute.setPriority(2);
            //返利维度
            rebatePolicyExecute.setRebateDimension(enumerationRepository.findOne("002467"));
            //品类
            rebatePolicyExecute.setClassify(rebatePolicyClassify.getClassify());
            rebatePolicyExecuteRepository.saveAndFlush(rebatePolicyExecute);
        });
        //品类与品牌
        rebatePolicy.getRebatePolicyClassifyBrandItems().forEach(rebatePolicyClassifyBrand -> {
            //创建返利执行表基础数据
            RebatePolicyExecute rebatePolicyExecute = createExecute(rebatePolicy);
            //返利政策明细号
            rebatePolicyExecute.setRebatePolicyItemId(rebatePolicyClassifyBrand.getId());
            //返利率/额
            rebatePolicyExecute.setRebate(rebatePolicyClassifyBrand.getRebate());
            //计算基数
            rebatePolicyExecute.setRebateBenchmark(rebatePolicyClassifyBrand.getRebateBenchmark());
            //优先级
            rebatePolicyExecute.setPriority(3);
            //返利维度
            rebatePolicyExecute.setRebateDimension(enumerationRepository.findOne("002469"));
            //品类
            rebatePolicyExecute.setClassify(rebatePolicyClassifyBrand.getClassify());
            //品牌
            rebatePolicyExecute.setBrand(rebatePolicyClassifyBrand.getBrand());
            rebatePolicyExecuteRepository.saveAndFlush(rebatePolicyExecute);
        });
        //商品
        rebatePolicy.getRebatePolicyProductItems().forEach(rebatePolicyProduct -> {
            //创建返利执行表基础数据
            RebatePolicyExecute rebatePolicyExecute = createExecute(rebatePolicy);
            //返利政策明细号
            rebatePolicyExecute.setRebatePolicyItemId(rebatePolicyProduct.getId());
            //返利率/额
            rebatePolicyExecute.setRebate(rebatePolicyProduct.getRebate());
            //计算基数
            rebatePolicyExecute.setRebateBenchmark(rebatePolicyProduct.getRebateBenchmark());
            //优先级
            rebatePolicyExecute.setPriority(4);
            //返利维度
            rebatePolicyExecute.setRebateDimension(enumerationRepository.findOne("002470"));
            //商品
            rebatePolicyExecute.setProduct(rebatePolicyProduct.getProduct());
            rebatePolicyExecuteRepository.saveAndFlush(rebatePolicyExecute);
        });
    }

    /**
     * 创建返利执行表基础数据
     *
     * @param rebatePolicy
     * @return
     */
    private RebatePolicyExecute createExecute(RebatePolicy rebatePolicy){
        RebatePolicyExecute rebatePolicyExecute = new RebatePolicyExecute();
        //返利政策
        rebatePolicyExecute.setRebatePolicy(rebatePolicy);
        //供应商
        rebatePolicyExecute.setSupplier(rebatePolicy.getSupplier());
        //返利类型
        rebatePolicyExecute.setPeriodType(rebatePolicy.getPeriodType());
        //有效期起
        rebatePolicyExecute.setStartDate(rebatePolicy.getStartDate());
        //有效期止
        rebatePolicyExecute.setEndDate(rebatePolicy.getEndDate());
        //平台公司
        rebatePolicyExecute.setPlatformCompany(rebatePolicy.getPlatformCompany());
        //费用类型
        rebatePolicyExecute.setIncomeType(rebatePolicy.getIncomeType());
        //合作方式
        rebatePolicyExecute.setCooperation(rebatePolicy.getCooperation());
        //返利税率
        rebatePolicyExecute.setTax(rebatePolicy.getTax());
        return rebatePolicyExecute;
    }

    /**
     * 定时任务计算返利
     *
     * @param request
     * @return
     */
    private void calculationRebate(SimpleRequest request){
        //三个时间 防止互相影响
        Calendar calendar = Calendar.getInstance();
        Calendar quarterCalendar = Calendar.getInstance();
        Calendar yearCalendar = Calendar.getInstance();
        String startDate;
        String endDate;


        //测试
//        JSONObject jo = request.getJO();
//        String stringDate = jo.getString("date");
//        Date date = DateUtil.parse(stringDate, DateUtil.SHOW_DATE_FORMAT);
//        calendar.setTime(date);
//        quarterCalendar.setTime(date);
//        yearCalendar.setTime(date);



        //只在一号进入
        if (calendar.get(Calendar.DATE) == 1) {
            //上月1号
            calendar.add(Calendar.MONTH, -1);
            startDate = DateUtil.format(calendar.getTime(),DateUtil.SHOW_DATE_FORMAT);
            //上月月末
            calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
            endDate = DateUtil.format(calendar.getTime(),DateUtil.SHOW_DATE_FORMAT);
            calculation(startDate,endDate,"001278");
            //季返 每个季度后一个月1号进入 calendar月份从0开始
            int quarterDate = quarterCalendar.get(Calendar.MONTH) + 1;
            if(quarterDate == 4 || quarterDate == 7 || quarterDate == 10 || quarterDate == 1 ){
                //往前取三个月
                quarterCalendar.add(Calendar.MONTH, -3);
                startDate = DateUtil.format(quarterCalendar.getTime(),DateUtil.SHOW_DATE_FORMAT);
                //上月月末
                quarterCalendar.set(Calendar.DAY_OF_MONTH, quarterCalendar.getActualMaximum(Calendar.DAY_OF_MONTH));
                quarterCalendar.add(Calendar.MONTH, +2);
                endDate = DateUtil.format(quarterCalendar.getTime(),DateUtil.SHOW_DATE_FORMAT);
                calculation(startDate,endDate,"001276");
            }
            //年返 只在每年1月1号进入 calendar月份从0开始
            int yearDate = yearCalendar.get(Calendar.MONTH) + 1;
            if(yearDate == 1){
                //去年1月
                yearCalendar.add(Calendar.MONTH, -12);
                startDate = DateUtil.format(yearCalendar.getTime(),DateUtil.SHOW_DATE_FORMAT);
                //去年年末
                yearCalendar.add(Calendar.MONTH, +11);
                yearCalendar.set(Calendar.DAY_OF_MONTH, yearCalendar.getActualMaximum(Calendar.DAY_OF_MONTH));
                endDate = DateUtil.format(yearCalendar.getTime(),DateUtil.SHOW_DATE_FORMAT);
                calculation(startDate,endDate,"001280");
            }
        }
    }
    private void calculation(String startDate,String endDate,String periodTypeId){
        //通过日期与返利类型查询返利政策
        List<Map> lists = rebatePolicyRepository.findRebatePolicy(endDate, periodTypeId);
        List<RebateCalculation> rebateCalculationList = new ArrayList<>();
        lists.forEach(list ->{
            String companyId;
            Cooperation cooperation = cooperationRepository.findOne(list.get("COOPERATION_ID").toString());
            String platformCompanyId = list.get("PLATFORM_COMPANY_ID").toString();
            String partnerId = (String)list.get("PARTNER_ID");
            //有赋能合同的取赋能公司
            if(partnerId != null && !"".equals(partnerId) ){
                companyId = partnerId;
            } else {
                companyId = platformCompanyId;
            }
            //通过日期供应商业务公司合作方式查询账单明细
            List<InvoiceItem> invoiceItemList = invoiceItemRepository.findByRebatePolicy(startDate, endDate, list.get("SUPPLIER_ID").toString(), companyId, cooperation.getInventoryMode());
            //账单明细查询返利执行表计算返利
            invoiceItemList.forEach(invoiceItem -> {
                Product product = invoiceItem.getProduct();
                List<RebatePolicyExecute> executeList = rebatePolicyExecuteRepository.findExecute(DateUtil.format(invoiceItem.getInvoice().getCreateDate(), DateUtil.SHOW_DATE_FORMAT),
                        invoiceItem.getInvoice().getPartner().getId(), product.getClassify().getId(), product.getBrand().getId(), product.getId(), list.get("ID").toString());
                if(executeList.isEmpty()) return;
                RebatePolicyExecute rebatePolicyExecute = executeList.get(0);
                //创建返利计算
                if(!rebateCalculationRepository.findByInvoiceItem(invoiceItem).isEmpty()) return;
                rebateCalculationList.add(createCalculation(rebatePolicyExecute,invoiceItem,platformCompanyId,partnerId));
            });
        });
        //根据供应商 平台公司 合作方式分组
        Map<String, List<RebateCalculation>> listMap = rebateCalculationList.stream().collect(Collectors.groupingBy(rebateCalculation ->
                rebateCalculation.getSupplier().getId() + ";" + rebateCalculation.getPlatformCompany().getId() + ";" + rebateCalculation.getCooperation().getId()));
        listMap.forEach((k,v) ->{
            //生成供应商收入单主表
            Income income = createIncome(v);
            Set<IncomeItem> incomeItemSet = new HashSet<>();
            //根据政策明细做二次分组
            Map<String, List<RebateCalculation>> collect = v.stream().collect(Collectors.groupingBy(RebateCalculation::getRebatePolicyItemId));
            //根据政策明细 + 多行返利计算明细生成
            collect.forEach((rebatePolicyItemId,list) -> incomeItemSet.add(createIncomeItem(rebatePolicyItemId,list)));
            //金额
            income.setAmount(incomeItemSet.stream().mapToDouble(IncomeItem :: getIncomeAmount).sum());
            income.setIncomeItems(incomeItemSet);
            income = this.invoke("income.supplier.approveByRebate", MapUtil.mapped(this.invoke("income.supplier.createByRebate", MapUtil.mapped(income))));
            Set<IncomeItem> incomeItems = income.getIncomeItems();
            collect.forEach((rebatePolicyItemId,list)->{
                IncomeItem item = incomeItems.stream().filter(incomeItem -> rebatePolicyItemId.equals(incomeItem.getRemark())).collect(Collectors.toList()).get(0);
                list.forEach(rebateCalculation -> rebateCalculation.setIncomeItem(item));
            });
        });
    }

    private IncomeItem createIncomeItem(String rebatePolicyItemId, List<RebateCalculation> list){
        IncomeItem incomeItem = new IncomeItem();
        //来源明细明细ID
        incomeItem.setRemark(rebatePolicyItemId);
        //业务开始日期
        List<RebateCalculation> rebateCalculations = list.stream().sorted(Comparator.comparing(RebateCalculation::getThirdTime)).collect(Collectors.toList());
        incomeItem.setStartDate(rebateCalculations.get(0).getThirdTime());
        //业务结束日期
        incomeItem.setEndDate(rebateCalculations.get(rebateCalculations.size()-1).getThirdTime());
        //费用类型
        incomeItem.setIncomeType(list.get(0).getIncomeType());
        //收入金额
        incomeItem.setIncomeAmount(list.stream().mapToDouble(RebateCalculation::getRebateAmount).sum());
        //备注
        incomeItem.setNote("根据" + rebatePolicyItemId + "自动计算");
        //税率
        incomeItem.setTax(list.get(0).getRebatePolicy().getTax());
        return incomeItem;
    }

    private Income createIncome(List<RebateCalculation> list){
        Income income = new Income();
        RebateCalculation rebateCalculation = list.get(0);
        //状态
        income.setState("approve");
        //公司
        PartyRole platformCompany = rebateCalculation.getPlatformCompany();
        income.setCompany(platformCompany);
        //部门
        income.setDept(deptRepository.findByDeptTypeIdAndCompanyId("000006", platformCompany.getId()));
        //合作方式
        income.setCooperation(rebateCalculation.getCooperation());
        //合作伙伴
        income.setPartner(rebateCalculation.getSupplier());
        //收入类别
        income.setInComeCategory(rebateCalculation.getIncomeType().getInComeCategory());
        //备注
        income.setNote("根据返利政策自动计算");
        return income;
    }

    private RebateCalculation createCalculation(RebatePolicyExecute rebatePolicyExecute,InvoiceItem invoiceItem,String platformCompanyId,String partnerId){
        RebateCalculation rebateCalculation = new RebateCalculation();
        //账单明细号
        rebateCalculation.setInvoiceItem(invoiceItem);
        //账单日期
        rebateCalculation.setThirdTime(invoiceItem.getInvoice().getThirdTime());
        //返利金额
        if("002466".equals(rebatePolicyExecute.getRebateBenchmark().getId())){
            //数量
            rebateCalculation.setRebateAmount(invoiceItem.getQty() * rebatePolicyExecute.getRebate());
        }else if("002465".equals(rebatePolicyExecute.getRebateBenchmark().getId())){
            //金额
            rebateCalculation.setRebateAmount(invoiceItem.getPriceSubtotal() * rebatePolicyExecute.getRebate());
        }
        //返利政策号
        rebateCalculation.setRebatePolicy(rebatePolicyExecute.getRebatePolicy());
        //返利政策明细号
        rebateCalculation.setRebatePolicyItemId(rebatePolicyExecute.getRebatePolicyItemId());
        //返利维度
        rebateCalculation.setRebateDimension(rebatePolicyExecute.getRebateDimension());
        //平台公司
        rebateCalculation.setPlatformCompany(partyRoleRepository.findOne(platformCompanyId));
        //业务公司
        if(partnerId != null) rebateCalculation.setPartner(partyRoleRepository.findOne(partnerId));
        //合作方式
        rebateCalculation.setCooperation(rebatePolicyExecute.getCooperation());
        //供应商
        rebateCalculation.setSupplier(rebatePolicyExecute.getSupplier());
        //费用类型
        rebateCalculation.setIncomeType(rebatePolicyExecute.getIncomeType());
        //返利类型
        rebateCalculation.setPeriodType(rebatePolicyExecute.getPeriodType());
        //计算基数
        rebateCalculation.setRebateBenchmark(rebatePolicyExecute.getRebateBenchmark());
        //返利率/额
        rebateCalculation.setRebate(rebatePolicyExecute.getRebate());
        //品类
        rebateCalculation.setClassify(rebatePolicyExecute.getClassify());
        //品牌
        rebateCalculation.setBrand(rebatePolicyExecute.getBrand());
        //商品
        rebateCalculation.setProduct(rebatePolicyExecute.getProduct());
        //数量
        rebateCalculation.setQty(invoiceItem.getQty());
        //金额
        rebateCalculation.setAmount(invoiceItem.getPriceSubtotal());
        return rebateCalculationRepository.saveAndFlush(rebateCalculation);
    }

}

